package com.bytedance.touch.remote

import android.annotation.TargetApi
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
import android.net.wifi.WifiManager
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import com.korion.channel.ChannelListener
import com.korion.channel.IChannel
import com.korion.channel.IServerListener
import com.korion.channel.Server
import java.net.Inet4Address
import java.net.NetworkInterface


class WorkService: Service(){

    companion object {
        private const val TAG = "WorkService"
    }
    private val mChannelSet = HashSet<IChannel>()
    private var mServer: Server? = null
    private var mPost: Int = 8000

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    private val mServerListener = object : IServerListener {

        override fun onServerClose() {
        }

        override fun onServerStart(localAddress: String?) {
            readyForegroundService()
        }

        override fun onNewConnection(channel: IChannel, host: String, port: Int) {
            mChannelSet.add(channel)
            channel.setListener(object : ChannelListener {
                override fun onConnected(channel: IChannel, host: String, port: Int) {
                    baseContext.showToast("$host:$port 接入")
                }

                override fun onFailure(error: String?) {
                    baseContext.showToast("Error: $error")
                    mChannelSet.remove(channel)
                }

                override fun onMessage(bytes: ByteArray, size: Int) {
                    Log.d(TAG, "onMessage:$bytes")
                }
            })
            channel.connect()
        }
    }

    override fun onCreate() {
        super.onCreate()
        val ip = getIpAddress()
        if (ip != null){
            mServer = Server.listen(ip, mPost, mServerListener)
        }
        readyForegroundService()
    }

    override fun onDestroy() {
        super.onDestroy()
        mServer?.stop()
        val it = mChannelSet.iterator()
        while (it.hasNext()){
            val channel = it.next()
            it.remove()
            if (channel.isConnect()){
                channel.close()
            }
        }
    }

    private fun readyForegroundService(){
        val host = mServer?.getLocalAddress() ?: "unknown"
        val channelId = createNotificationChannel()
        val builder = if (channelId != null){
            NotificationCompat.Builder(baseContext, channelId)
        } else {
            NotificationCompat.Builder(baseContext)
        }
        builder.setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle("channel service")
            .setContentText("listen: $host")
            .setOngoing(true)
        startForeground(1, builder.build())
    }

    private fun createNotificationChannel(): String?{
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            val channelId = "$packageName#channel"
            val channelName = "Channel Service"
            val level = NotificationManager.IMPORTANCE_LOW
            val channel = NotificationChannel(channelId, channelName, level)
            channel.description = "通道监听服务"
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
            return channelId
        }
        return null
    }

    private fun getIpAddress(): String?{

        val manager = baseContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val networkInfo = manager.activeNetworkInfo
        if (networkInfo != null && networkInfo.isConnected){
            if (networkInfo.type == ConnectivityManager.TYPE_MOBILE){
                val interfaces = NetworkInterface.getNetworkInterfaces()
                while(interfaces.hasMoreElements()){
                    val netIf = interfaces.nextElement()
                    val inetAddress = netIf.inetAddresses
                    while (inetAddress.hasMoreElements()){
                        val inetAddress = inetAddress.nextElement()
                        if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address){
                            return inetAddress.hostAddress
                        }
                    }
                }
            } else if (networkInfo.type == ConnectivityManager.TYPE_WIFI){
                val wifiManager = baseContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
                val wifiInfo = wifiManager.connectionInfo
                val ipAddress = intIP2StringIP(wifiInfo.ipAddress)
                return ipAddress
            }
        }
        return null
    }

    private fun intIP2StringIP(ip: Int): String {
        return "${ip and 0xFF}.${ip.shr(8) and 0xFF}.${ip.shr(16) and 0xFF}.${ip.shr(24) and 0xFF}"
    }

}




